package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleConfigMapper;
import com.heima.article.mapper.ApArticleContentMapper;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.mapper.ApAuthorMapper;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.GeneratePageService;
import com.heima.common.exception.CustException;
import com.heima.constants.message.ArticleConstants;
import com.heima.constants.message.NewsUpOrDownConstants;
import com.heima.feigns.AdminFeign;
import com.heima.feigns.WemediaFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dtos.ArticleHomeDTO;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wmmedia.pojos.WmNews;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {
    @Autowired
    private WemediaFeign wmUserFeign;
    @Autowired
    private AdminFeign adminFeign;
    @Autowired
    private ApAuthorMapper apAuthorMapper;
    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private ApArticleConfigMapper apArticleConfigMapper;
    @Autowired
    private ApArticleContentMapper apArticleContentMapper;
    @Autowired
    GeneratePageService generatePageService;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Value("${file.oss.web-site}")
    private String webSite;
    @Value("${file.minio.readPath}")
    String readPath;

    //文章发布功能
    @Override
    @GlobalTransactional(rollbackFor = Exception.class, timeoutMills = 100000)
    public void publishArticle(Integer id) {
        //非空判断
        if (id == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
        //根据文章id查询wmNews
        ResponseResult<WmNews> wmNewsResp = wmUserFeign.findWmNewsById(id);
        //非空判断
        if (wmNewsResp.getCode() != 0) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "文章查询出错!");
        }
        if (wmNewsResp.getData() == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "未查询到该文章!");
        }
        //获取wmNews,根据wmNewsId查询是否发布过
        WmNews wmNews = wmNewsResp.getData();
        //判断文章状态是否审核通过
        if (wmNews.getStatus() == 4 || wmNews.getStatus() == 8) {
            //审核通过,根据用户id查询作者
            ApAuthor author = apAuthorMapper.selectOne(Wrappers.<ApAuthor>lambdaQuery().eq(ApAuthor::getWmUserId, wmNews.getUserId()));
            //判断是否查询到作者
            if (author == null) {
                CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "未查询到该作者!");
            }
            //审核通过,判断是否到达文章发布时间
            if (wmNews.getPublishTime().getTime() > new Date().getTime()) {
                CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "文章暂未到达发布时间!");
            }
            //根据频道id查询频道
            ResponseResult<AdChannel> adChannelResp = adminFeign.findOne(wmNews.getChannelId());
            //判断是否查询到频道
            if (adChannelResp.getCode() != 0) {
                CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "频道查询出错!!");
            }
            if (adChannelResp.getData() == null) {
                CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "未查询到该频道!");
            }
            //获取频道
            AdChannel channel = adChannelResp.getData();
            //创建apArticle
            ApArticle apArticle = new ApArticle();
            apArticle.setTitle(wmNews.getTitle());
            apArticle.setImages(wmNews.getImages());
            apArticle.setLabels(wmNews.getLabels());
            apArticle.setAuthorId(author.getId().longValue());
            apArticle.setAuthorName(author.getName());
            apArticle.setChannelName(channel.getName());
            apArticle.setChannelId(wmNews.getChannelId());
            apArticle.setLayout((wmNews.getType()));
            apArticle.setFlag((byte) 0);  //文章类型
            //判断wmNews表和article表是否有关联
            if (wmNews.getArticleId() == null) {
                //没有关联,新增文章信息
                apArticle.setCreatedTime(new Date());
                apArticle.setLikes(0);  //点赞数
                apArticle.setCollection(0);  //收藏数
                apArticle.setComment(0);  //评论数
                apArticle.setViews(0);  //阅读数
                apArticle.setPublishTime(wmNews.getPublishTime());
                apArticle.setSyncStatus(false);
                apArticle.setOrigin(false);
                //将apArticle保存到数据库
                apArticleMapper.insert(apArticle);
            } else {
                //有关联,根据文章id查询文章信息
                ApArticle apArticle1 = apArticleMapper.selectById(wmNews.getArticleId());
                if (apArticle1 == null) {
                    CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "关联的文章不存在");
                }
                //有关联,且文章存在,修改文章信息表,将Id赋值给对象
                apArticle.setId(wmNews.getArticleId());  //文章id
                //将apArticle修改到数据库
                apArticleMapper.updateById(apArticle);
                //重新查询apArticle
                apArticle = apArticleMapper.selectById(wmNews.getArticleId());
                //删除之前的apArticleConfig和apArticleContent
                apArticleConfigMapper.delete(Wrappers.<ApArticleConfig>lambdaQuery().eq(ApArticleConfig::getArticleId, wmNews.getArticleId()));
                apArticleContentMapper.delete(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, wmNews.getArticleId()));
            }
            //新增文章时生成静态页
            generatePageService.generateArticlePage(wmNews.getContent(), apArticle);
            //发送MQ消息,通知ES添加文章索引
            rabbitTemplate.convertAndSend(NewsUpOrDownConstants.NEWS_UP_FOR_ES_QUEUE, apArticle.getId());

            //创建apArticleConfig
            ApArticleConfig apArticleConfig = new ApArticleConfig();
            apArticleConfig.setArticleId(apArticle.getId());
            apArticleConfig.setIsComment(true);
            apArticleConfig.setIsForward(true);  //是否转发
            apArticleConfig.setIsDown(false);  //是否下架
            apArticleConfig.setIsDelete(false);  //是否已删除
            //将创建apArticleConfig保存到数据
            apArticleConfigMapper.insert(apArticleConfig);

            //创建apArticleContent
            ApArticleContent apArticleContent = new ApArticleContent();
            apArticleContent.setArticleId(apArticle.getId());
            apArticleContent.setContent(wmNews.getContent());
            //将apArticleContent保存到数据库
            apArticleContentMapper.insert(apArticleContent);

            //文章发布成功,修改文章状态为9  将文章id设置给wmNews
            wmNews.setStatus((short) 9);
            wmNews.setArticleId(apArticle.getId());
            wmUserFeign.updateWmNews(wmNews);
            return;
        }
        //审核不通过,修改文章状态为2
        wmNews.setStatus((short) 2);
        wmUserFeign.updateWmNews(wmNews);
        CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "该文章暂未通过审核,请审核通过后再提交!");
    }

    ////app端文章列表功能
    @Override
    public ResponseResult load(Short loadtypeLoadNew, ArticleHomeDTO dto) {
        //非空判断
        if (loadtypeLoadNew == null && dto == null) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }

        //检查参数
        if (dto.getSize() == null) {
            dto.setSize(10);
        }
        if (dto.getMaxBehotTime() == null) {
            dto.setMaxBehotTime(new Date());
        }
        if (dto.getMinBehotTime() == null) {
            dto.setMinBehotTime(new Date());
        }
        if (dto.getTag() == null) {
            dto.setTag(ArticleConstants.DEFAULT_TAG);
        }
        //根据条件查询文章列表
        List<ApArticle> articleList = apArticleMapper.loadNew(loadtypeLoadNew, dto);
        //非空判断
        if (articleList == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "未查询到文章!");
        }
        //加载文章列表时 添加静态资源访问前缀路径
        for (ApArticle apArticle : articleList) {
            apArticle.setStaticUrl(readPath + apArticle.getStaticUrl());
            String images = Arrays.stream(apArticle.getImages().split(",")).map(image -> {
                return image = webSite + image;
            }).collect(Collectors.joining(","));
            apArticle.setImages(images);
        }
        return ResponseResult.okResult(articleList);
    }

    //根据参数加载文章列表  0为加载更多  1为加载最新    firstPage 是否为首页
    @Override
    public ResponseResult load2(Short loadtype, ArticleHomeDTO dto, boolean firstPage) {
        if (firstPage) {
            //首页,根据频道id查询redis中的热点文章
            String articleListJson = redisTemplate.opsForValue().get(ArticleConstants.HOT_ARTICLE_FIRST_PAGE + dto.getTag());
            //非空判断
            if (StringUtils.isNotBlank(articleListJson)) {
                //将热点文章的JSON字符串解析成ApArticle对象
                List<ApArticle> apArticles = JSON.parseArray(articleListJson, ApArticle.class);
                //遍历集合
                for (ApArticle apArticle : apArticles) {
                    apArticle.setStaticUrl(readPath + apArticle.getStaticUrl());
                    String images = Arrays.stream(apArticle.getImages().split(",")).map(image -> {
                        return image = webSite + image;
                    }).collect(Collectors.joining(","));
                    apArticle.setImages(images);
                }
                ResponseResult result = ResponseResult.okResult(apArticles);
                result.setHost(webSite);
                return result;
            }
        }
        //不是首页
        return load(loadtype, dto);
    }
}